<style>
    .pic-wrapper {
        width: 660px;
        margin: 50px auto;
    }
    
    .pic-wrapper li {
        float: left;
        margin-left: 20px;
        margin-bottom: 20px;
        border: 2px solid transparent;
        box-sizing: border-box;
        width: 200px;
        height: 200px;
        overflow: hidden;
        transition: all .2s linear;
    }
    
    .pic-wrapper li>img {
        width: 200px;
        height: 200px;
    }
</style>
</head>

<body>
    <div class="pic-wrapper">
        <ul>
            <li><img ondragstart="return false" src="/img/picture/person1.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person2.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person3.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person4.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person5.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person6.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person7.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person8.jpg" alt=""></li>
            <li><img ondragstart="return false" src="/img/picture/person9.jpg" alt=""></li>
        </ul>
    </div>

    <script>
        lists = document.querySelectorAll('pic-wrapper ul>li');
        var n = 0;
        var len;
        var arr = [];
        var i;

        // 获取偏移值
        lists.forEach(function(list, index) {
            list.setAttribute('index', index);
            list.style.left = list.offsetLeft + 'px';
            list.style.top = list.offsetTop + 'px';
            arr.push([list.offsetLeft, list.offsetTop]);
            setTimeout(function() {
                setPosition(list);
            }, 0);
        });
        // 定位绑定
        function setPosition(ele) {
            ele.style.position = 'absolute';
            ele.style.margin = 0;
        }

        //事件绑定
        lists.forEach(function(list) {
            list.onmousedown = function(e) {
                var initX = e.pageX;
                var initY = e.pageY;
                var staticX = this.offsetLeft;
                var staticY = this.offsetTop;

                this.style.zIndex = ++n;
                document.onmousemove = function(e) {
                    var currX = e.pageX;
                    var currY = e.pageY;
                    list.style.left = currX - initX + staticX + 'px';
                    list.style.top = currY - initY + staticY + 'px';

                    lists.forEach(function(ele) {
                        ele.style.borderColor = 'transparent';
                    })
                    if (getNearEle(list)) {
                        getNearEle(list).style.borderColor = 'red';
                    }
                }
                document.onmouseup = function() {
                    document.onmousemove = null;
                    var li = getNearEle(list);
                    move(list, li);
                }
            }
        });

        //交换位置
        function move(o1, o2) {
            var index1 = o1.getAttribute('index');
            var index2 = o2.getAttribute('index');

            o2.style.left = arr[index1][0] + 'px';
            o2.style.top = arr[index1][1] + 'px';
            o1.style.left = arr[index2][0] + 'px';
            o1.style.top = arr[index2][1] + 'px';
            o1.setAttribute('index', index2);
            o2.setAttribute('index', index1);
        }

        // 得到距离最近元素
        function getNearEle(obj) {
            var num = 10000;
            lists.forEach(function(ele, index) {
                if (impactCheck(obj, ele) && obj != ele) {
                    len = checkLength(obj, ele);
                    if (len < num) {
                        num = len;
                        i = index;
                    }
                }
            })
            return lists[i];
        }

        //检测长度
        function checkLength(o1, o2) {
            var l1 = Math.pow(o1.offsetLeft - o2.offsetLeft, 2);
            var l2 = Math.pow(o1.offsetTop - o2.offsetTop, 2);
            return Math.sqrt(l1 + l2);
        }

        // impact碰撞检测
        function impactCheck(o1, o2) {
            var t1 = o1.offsetHeight + o1.offsetTop;
            var t2 = o2.offsetTop;
            var r1 = o1.offsetLeft;
            var r2 = o2.offsetLeft + o2.offsetWidth;
            var b1 = o1.offsetTop;
            var b2 = o2.offsetTop + o2.offSetHeight;
            var l1 = o1.offsetWidth + o1.offsetLeft;
            var l2 = o2.offsetLeft;
            if (t1 < t2 || r1 > r2 || b1 > b2 || l2 > l1) {
                return false;
            }
            return true;
        }
    </script>